// original code adapted from https://www.shadertoy.com/view/ltXGRj
#include "octane-oslintrin.h"
vector xz(vector vec)
{
    return vector(vec[0],vec[2], 0);
}

vector xy(vector vec)
{
    return vector(vec[0], vec[1], 0);
}

vector vec2(float a, float b)
{
    return vector(a,b,0);
}

vector frac(vector v)
{
    return v - vector(floor(v[0]), floor(v[1]), floor(v[2]));
}

float fracf(float f)
{
    return f - floor(v);
}


float planeSDF(vector p)
{
    float w = 1.0 / sqrt(2);
    vector n = vector(0, w, 0);
    return dot(p, n) + w; 
}

float displace(float d1,vector p, vector noise)
{
    float d2 = noise[0];
    return d1 + d2;
}
    
float sphereSDF(vector p, float r)
{
    return length(p) -r;
}

float boxSDF(vector p, float size)
{
  return length(max(abs(p)- vector(size),0.0));
}

float repeat_sphere(vector p, vector c)
{
    vector q = mod(p,c) - 0.5*c;
    
    return boxSDF(q, 7.0);
}

float smin(float a, float b, float k)
{
    float res = exp(-k*a) + exp(-k*b);
    return -log(res)/k;
}

float sceneSDF(vector p, vector noise)
{
    float terrain = displace(planeSDF(p), p, noise);
    return terrain;
}

vector yzx(vector v)
{
    return vector(v[1], v[2], v[0]);
}

vector yz(vector v)
{
    return vector(v[1], v[2], 0);
}

vector zx(vector v)
{
    return vector(v[2], v[0], 0);
}

float DE(vector p, float t, float dens){//fur ball
	p+=sin(3*yzx(p)*(10.0+5.0*sin(t*0.1))+-t*2.0)*0.02;
	float r=length(p);
	if(r<1.0){
		vector p2=p*p;
		vector v=(p2[0]>p2[1] && p2[0]>p2[2])?yz(p)/p[0]:(p2[1]>p2[2])?zx(p)/p[1]:xy(p)/p[2];
		float m=dens;
		v=mod(v+m,4.0*m)-m;
		float r2=(length(v)-0.03+0.04*r);
		r-=0.8;
		r=r2;
	}else r-=.9;
	return r;
}


shader OslGeometry(
    float quality = 0.9,
    float t = 1,
    float dens = 0.04,
    output _sdf c = _SDFDEF)
{
    int i = 1;

    // to enable some animation, uncomment this line:
    //i = _wipes();

    c.dist = (1-quality) * DE(P, i * t + time, dens);

}
